package com.cby.code.optimization;

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.view.Choreographer;

import com.cby.code.util.CbyLogUtils;

/**
 * @description: UI 每一帧的的绘制时间间隔探测，并且判断多少帧被跳过
 * @author: ChenBaoYang
 * @createDate: 2022/3/3 2:19 下午
 */
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public class UIFrameDetector implements Choreographer.FrameCallback {

    private static final String TAG = "UIFrameDetector";

    /**
     * 设备刷新评率，按照1000/60 => 16.6ms
     */
    public static final float DEVICE_REFRESH_RATE_MS = 16.6f;

    /**
     * 纳秒为单位 {@linkplain Choreographer.FrameCallback#doFrame(long)} 回调的是纳秒
     */
    public static long lastFrameTimeNanos = 0;

    /**
     * 纳秒为单位
     */
    public static long currentFrameTimeNanos = 0;

    public void start() {
        Choreographer.getInstance().postFrameCallback(UIFrameDetector.getInstance());
    }

    public void stop() {
        Choreographer.getInstance().removeFrameCallback(UIFrameDetector.getInstance());
    }

    private UIFrameDetector() {

    }

    public static UIFrameDetector getInstance() {
        return SingletonHolder.INSTANCE;
    }

    @Override
    public void doFrame(long frameTimeNanos) {
        if (lastFrameTimeNanos == 0) {
            lastFrameTimeNanos = frameTimeNanos;
            Choreographer.getInstance().postFrameCallback(this);
            return;
        }
        currentFrameTimeNanos = frameTimeNanos;
        float value = (currentFrameTimeNanos - lastFrameTimeNanos) / 1000000.0f;

        final int skipFrameCount = skipFrameCount(lastFrameTimeNanos, currentFrameTimeNanos, DEVICE_REFRESH_RATE_MS);
        CbyLogUtils.flog(TAG, "两次绘制时间间隔 value = " + value + " frameTimeNanos=" + frameTimeNanos + "  currentFrameTimeNanos = " + currentFrameTimeNanos + "  skipFrameCount = " + skipFrameCount + "");
        lastFrameTimeNanos = currentFrameTimeNanos;
        Choreographer.getInstance().postFrameCallback(this);
    }

    /**
     * 计算跳过多少帧
     *
     * @param start             开始时间 （单位纳秒）
     * @param end               结束时间 （单位纳秒）
     * @param deviceRefreshRate 刷新频率
     * @return
     */
    private int skipFrameCount(long start, long end, float deviceRefreshRate) {
        int count = 0;
        // 计算两个时间的差值
        long diffNs = end - start;
        // 换成成毫秒
        long diffMs = Math.round(diffNs / 1000000.0f);

        // Math.round 进行取整四舍五入
        long dev = Math.round(deviceRefreshRate);
        if (diffMs > dev) {
            long skipCount = diffMs / dev;
            count = (int) skipCount;
        }
        return count;
    }

    private static class SingletonHolder {
        private static final UIFrameDetector INSTANCE = new UIFrameDetector();
    }
}
